import asyncio
import json
import os
import platform
import sys
import threading
import time
from datetime import datetime
from typing import Optional, Callable

import keyboard
from bleak import BleakClient, BleakScanner

from BatteryDataParser import BatteryDataParser
from UARTDataParser import UARTDataParser


class AdvancedBLEScanner:
    def __init__(self):
        self.devices = {}
        self.filters = {}

        self.connected_client: Optional[BleakClient] = None
        self.connection_callbacks = {
            'on_connected': None,
            'on_disconnected': None,
            'on_connection_failed': None
        }
        self.notification_handlers = {}

        # 线程控制标志
        self.running = False
        self.threads = []

        # 数据存储 - 使用线程安全的数据结构
        self.battery_level = None
        self.uart_data = []  # 存储UART数据，只保留最近的10条
        self.connection_status = False
        self.current_device_address = None

        # 线程同步锁
        self.uart_lock = threading.Lock()
        self.data_updated = threading.Event()

        # 重连相关
        self.reconnect_attempts = 0
        self.max_reconnect_attempts = 3
        self.is_reconnecting = False

        # 电池数据解析器
        self.battery_parser = BatteryDataParser()
        # 电池相关属性
        self.battery_level = None
        self.battery_voltage = None

        # UART数据解析器
        self.uart_parser = UARTDataParser()
        # 设置数据回调
        self.uart_parser.set_data_callbacks(
            on_rocker_data=self._on_rocker_data,
            on_key_data=self._on_key_data,
            on_frame_error=self._on_frame_error
        )

        # 电池服务UUID
        self.UUID_BATTERY_SERVICE = "0000180f-0000-1000-8000-00805f9b34fb"
        self.UUID_BATTERY_CHAR_READ = "00002a19-0000-1000-8000-00805f9b34fb"
        self.UUID_CLIENT_CHARACTERISTIC_CONFIG = "00002902-0000-1000-8000-00805f9b34fb"
        self.UUID_UART_TX = "6e400003-b5a3-f393-e0a9-e50e24dcca9e"

        self.is_windows = platform.system() == "Windows"
        self.connected_devices_file = "connected_devices.json"

    def save_connected_device_info(self, device_info):
        """保存已连接设备信息到JSON文件"""
        try:
            # 添加连接时间戳
            device_data = device_info.copy()
            device_data['connection_time'] = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            device_data['last_connected'] = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            device_data['connection_count'] = 1

            # 读取现有的设备信息
            existing_devices = {}
            if os.path.exists(self.connected_devices_file):
                try:
                    with open(self.connected_devices_file, 'r', encoding='utf-8') as f:
                        existing_devices = json.load(f)
                except:
                    existing_devices = {}

            # 更新设备信息
            device_address = device_info['address']
            if device_address in existing_devices:
                # 更新现有设备信息
                existing_device = existing_devices[device_address]
                device_data['connection_count'] = existing_device.get('connection_count', 0) + 1
                device_data['first_connection_time'] = existing_device.get('first_connection_time',
                                                                           device_data['connection_time'])
                # 保留历史连接记录
                device_data['connection_history'] = existing_device.get('connection_history', [])
                device_data['connection_history'].append({
                    'time': device_data['connection_time'],
                    'rssi': device_info.get('rssi', 'N/A')
                })
                # 限制历史记录数量
                if len(device_data['connection_history']) > 10:
                    device_data['connection_history'] = device_data['connection_history'][-10:]
            else:
                # 新设备
                device_data['first_connection_time'] = device_data['connection_time']
                device_data['connection_history'] = [{
                    'time': device_data['connection_time'],
                    'rssi': device_info.get('rssi', 'N/A')
                }]

            existing_devices[device_address] = device_data

            # 保存到文件
            with open(self.connected_devices_file, 'w', encoding='utf-8') as f:
                json.dump(existing_devices, f, indent=2, ensure_ascii=False)

            print(f"✅ 设备信息已保存到: {self.connected_devices_file}")
            return True

        except Exception as e:
            print(f"❌ 保存设备信息失败: {e}")
            return False

    def load_connected_devices(self):
        """从JSON文件加载已连接设备信息"""
        try:
            if os.path.exists(self.connected_devices_file):
                with open(self.connected_devices_file, 'r', encoding='utf-8') as f:
                    return json.load(f)
            return {}
        except Exception as e:
            print(f"❌ 加载设备信息失败: {e}")
            return {}

    def get_device_connection_stats(self, device_address):
        """获取设备的连接统计信息"""
        devices = self.load_connected_devices()
        if device_address in devices:
            device_info = devices[device_address]
            return {
                'connection_count': device_info.get('connection_count', 0),
                'first_connection': device_info.get('first_connection_time', '未知'),
                'last_connection': device_info.get('last_connected', '未知')
            }
        return None

    def print_device_history(self):
        """打印设备连接历史"""
        devices = self.load_connected_devices()
        if not devices:
            print("📝 暂无设备连接历史")
            return

        print("\n" + "=" * 60)
        print("设备连接历史")
        print("=" * 60)

        for i, (address, info) in enumerate(devices.items(), 1):
            print(f"{i}. {info.get('name', '未知设备')}")
            print(f"   地址: {address}")
            print(f"   连接次数: {info.get('connection_count', 0)}")
            print(f"   首次连接: {info.get('first_connection_time', '未知')}")
            print(f"   最后连接: {info.get('last_connected', '未知')}")
            print(f"   信号强度: {info.get('rssi', 'N/A')} dBm")
            print("-" * 40)

    def _format_mac_address(self, address):
        """格式化MAC地址以适应不同平台"""
        if self.is_windows:
            # Windows可能需要不同的MAC地址格式
            # 尝试多种格式
            if ':' in address:
                # 格式1: 保持冒号分隔
                return address
            else:
                # 格式2: 添加冒号
                return ':'.join([address[i:i + 2] for i in range(0, len(address), 2)])
        else:
            # Linux/Android: 保持原样
            return address

    def _on_rocker_data(self, frame_num: int, rocker1: int, rocker2: int):
        """摇杆数据回调"""
        # 可以在这里添加摇杆数据的特殊处理
        # 例如：控制游戏角色、机器人等
        if rocker1 != 0 or rocker2 != 0:
            print(f"🎮 摇杆数据: 帧号={frame_num}, X={rocker1}, Y={rocker2}")

    def _on_key_data(self, frame_num: int, key_status: int):
        """按键数据回调"""
        # 可以在这里添加按键数据的特殊处理
        # 解析按键状态位

        print(f"🎯 按键状态: {key_status}")

    def _on_frame_error(self, data_type: str, error_count: int, last_num: int, now_num: int):
        """帧错误回调"""
        print(f"⚠️ {data_type}帧号错误: 错误计数={error_count}, 上次={last_num}, 当前={now_num}")

    async def setup_battery_service(self):
        """设置电池服务 - 对应Android的ReadAJNotify方法"""
        if not self.connected_client or not self.connected_client.is_connected:
            print("❌ 设备未连接，无法设置电池服务")
            return False

        try:
            print("🔋 开始设置电池服务...")

            # 获取电池服务
            battery_service = self.connected_client.services.get_service(self.UUID_BATTERY_SERVICE)
            if not battery_service:
                print("❌ 未找到电池服务")
                return False

            # 获取电池特征
            battery_characteristic = battery_service.get_characteristic(self.UUID_BATTERY_CHAR_READ)
            if not battery_characteristic:
                print("❌ 未找到电池特征")
                return False

            print("✅ 找到电池服务特征")

            # 启用电池通知
            await self._enable_battery_notifications(battery_characteristic)

            # 延迟读取电池数据（模拟Android的Thread.sleep(1000)）
            await asyncio.sleep(1.0)
            await self.read_battery_characteristic()

            # 再次延迟读取
            await asyncio.sleep(1.0)
            await self.read_battery_characteristic()

            # 检查是否支持通知和读取，设置描述符
            # if await self._check_battery_properties(battery_characteristic):
            #     await self._setup_battery_notify_descriptor(battery_characteristic)

            return True

        except Exception as e:
            print(f"❌ 设置电池服务失败: {e}")
            return False

    async def _enable_battery_notifications(self, battery_characteristic):
        """启用电池电量通知"""
        try:
            # 检查特征是否支持通知
            if 'notify' not in battery_characteristic.properties:
                print("⚠️ 电池特征不支持通知")
                return False

            # 启用通知
            await self.connected_client.start_notify(
                battery_characteristic.uuid,
                self._on_battery_data_changed
            )
            # 记录电池通知处理器
            self.notification_handlers[battery_characteristic.uuid] = self._on_battery_data_changed
            print("✅ 电池电量通知已启用")
            return True

        except Exception as e:
            print(f"❌ 启用电池通知失败: {e}")
            return False

    # async def _setup_battery_notify_descriptor(self, battery_characteristic):
    #     """设置电池通知描述符 - 对应Android的descriptor设置"""
    #     try:
    #         # 获取特征的所有描述符
    #         descriptors = battery_characteristic.descriptors
    #
    #         for descriptor in descriptors:
    #             # 检查是否是客户端特征配置描述符
    #             if descriptor.uuid == self.UUID_CLIENT_CHARACTERISTIC_CONFIG:
    #                 # 启用通知 (0x0001)
    #                 enable_notification = bytes([0x01, 0x00])
    #                 await self.connected_client.write_gatt_descriptor(descriptor.uuid, enable_notification)
    #                 print("✅ 电池通知描述符已设置")
    #                 return True
    #
    #         print("⚠️ 未找到电池通知描述符")
    #         return False
    #
    #     except Exception as e:
    #         print(f"❌ 设置电池通知描述符失败: {e}")
    #         return False

    # async def _check_battery_properties(self, battery_characteristic):
    #     """检查电池特征属性"""
    #     properties = battery_characteristic.properties
    #     has_notify = 'notify' in properties
    #     has_read = 'read' in properties
    #
    #     print(f"🔋 电池特征属性: {properties}")
    #     print(f"   - 支持通知: {has_notify}")
    #     print(f"   - 支持读取: {has_read}")
    #
    #     return has_notify and has_read

    def _on_battery_data_changed(self, sender, data):
        """电池数据变化回调 - 对应Android的onCharacteristicChanged"""
        print(f"🔋 电池数据通知: {data.hex()}")
        percentage, voltage = self.battery_parser.parse_battery_data(data)

        if percentage is not None:
            self.battery_level = percentage
            print(f"🔋 电池电量更新: {percentage}%")

        if voltage is not None:
            self.battery_voltage = voltage
            print(f"⚡ 电池电压更新: {voltage}mV ({voltage / 1000:.2f}V)")

    async def read_battery_characteristic(self):
        """读取电池特征值"""
        try:
            if not self.connected_client or not self.connected_client.is_connected:
                print("❌ 设备未连接")
                return None, None

            value = await self.connected_client.read_gatt_char(self.UUID_BATTERY_CHAR_READ)

            if value:
                print(f"🔋 读取电池数据成功: {value.hex()}")
                percentage, voltage = self.battery_parser.parse_battery_data(value)

                self.battery_level = percentage
                self.battery_voltage = voltage

                return percentage, voltage
            else:
                print("❌ 读取的电池数据为空")
                return None, None

        except Exception as e:
            print(f"❌ 读取电池特征失败: {e}")
            return None, None

    def set_connection_callbacks(self, on_connected=None, on_disconnected=None, on_connection_failed=None):
        """设置连接状态回调函数"""
        self.connection_callbacks = {
            'on_connected': on_connected,
            'on_disconnected': on_disconnected,
            'on_connection_failed': on_connection_failed
        }

    def set_filter(self, name_prefixes=None, rssi_threshold=None, service_uuid=None):
        """设置过滤条件"""
        self.filters = {
            'name_prefixes': name_prefixes or [],
            'rssi': rssi_threshold,
            'service_uuid': service_uuid
        }

    def passes_filters(self, device_info):
        """检查设备是否通过过滤器"""
        device_name = device_info['name']

        if self.filters.get('name_prefixes'):
            matches_any_prefix = any(
                device_name.startswith(prefix)
                for prefix in self.filters['name_prefixes']
            )
            if not matches_any_prefix:
                return False

        if self.filters.get('rssi') and device_info['rssi'] < self.filters['rssi']:
            return False

        if self.filters.get('service_uuid') and device_info['uuids']:
            if self.filters['service_uuid'] not in device_info['uuids']:
                return False

        return True

    async def scan_with_filters(self, duration=30):
        """带过滤的扫描"""
        print("开始高级BLE扫描...")
        print(
            f"过滤条件: 名称前缀={self.filters.get('name_prefixes', '无')}, RSSI阈值={self.filters.get('rssi', '无')}")

        def detection_callback(device, advertisement_data):
            device_info = {
                'name': device.name or 'Unknown',
                'address': device.address,
                'rssi': advertisement_data.rssi,
                'local_name': advertisement_data.local_name,
                'tx_power': advertisement_data.tx_power,
                'uuids': advertisement_data.service_uuids or [],
                'manufacturer_data': advertisement_data.manufacturer_data
            }

            if self.passes_filters(device_info):
                if device.address not in self.devices:
                    print(f"✅ 发现设备: {device_info['name']} - {device_info['address']} - RSSI: {device_info['rssi']}")
                self.devices[device.address] = device_info

        async with BleakScanner(detection_callback=detection_callback):
            await asyncio.sleep(duration)

        print(f"\n扫描完成，共发现 {len(self.devices)} 个匹配设备")
        return self.devices

    def print_device_list(self):
        """打印设备列表供用户选择"""
        if not self.devices:
            print("没有发现设备")
            return None

        print("\n" + "=" * 60)
        print("发现以下设备:")
        print("=" * 60)

        sorted_devices = sorted(
            self.devices.items(),
            key=lambda x: x[1]['rssi'],
            reverse=True
        )

        device_list = []
        for i, (addr, device_info) in enumerate(sorted_devices, 1):
            print(f"{i}. {device_info['name']}")
            print(f"   地址: {addr}")
            print(f"   信号强度: {device_info['rssi']} dBm")
            if device_info['local_name']:
                print(f"   本地名称: {device_info['local_name']}")
            print(f"   服务UUID: {device_info['uuids'][:2] if device_info['uuids'] else '无'}")
            print("-" * 40)
            device_list.append((addr, device_info))

        return device_list

    def _disconnected_callback(self, client):
        """断开连接回调"""
        print(f"⚠️ 设备 {client.address} 已断开连接")
        self.connected_client = None
        self.connection_status = False

        # 触发自动重连
        # if self.running and self.current_device_address and not self.is_reconnecting:
        #     asyncio.create_task(self._auto_reconnect())

        if self.connection_callbacks['on_disconnected']:
            self.connection_callbacks['on_disconnected'](client.address)

    async def _auto_reconnect(self):
        """自动重连"""
        if self.is_reconnecting or self.reconnect_attempts >= self.max_reconnect_attempts:
            return

        self.is_reconnecting = True
        print(f"🔄 尝试自动重连 ({self.reconnect_attempts + 1}/{self.max_reconnect_attempts})...")

        try:
            await asyncio.sleep(2)  # 等待2秒后重连

            client = await self.connect_to_device(self.current_device_address, timeout=10.0)
            if client and client.is_connected:
                print("✅ 自动重连成功!")
                self.reconnect_attempts = 0

                # 重新启用UART通知
                uart_tx_uuid = self.UUID_UART_TX
                if uart_tx_uuid not in self.notification_handlers:
                    def uart_notification_handler(sender, data):
                        self._add_uart_data(sender, data)

                    await self.start_notifications(uart_tx_uuid, uart_notification_handler)

            else:
                self.reconnect_attempts += 1
                print(f"❌ 自动重连失败，已尝试 {self.reconnect_attempts} 次")

        except Exception as e:
            self.reconnect_attempts += 1
            print(f"❌ 自动重连错误: {e}")
        finally:
            self.is_reconnecting = False

    def _add_uart_data(self, sender, data):
        """添加UART数据，只保留最近的10条 - 线程安全版本"""

        # 首先进行数据解析
        self.uart_parser.on_data_notify(data)

        try:
            text = data.decode('utf-8', errors='ignore')
            timestamp = time.strftime("%H:%M:%S")
            hex_data = data.hex()
            # print(f"[{timestamp}] 📥 UART数据来自 {sender}: {text}")

            # 使用锁保护共享数据
            with self.uart_lock:
                # 添加新数据到列表开头（最新的在前面）
                self.uart_data.insert(0, (timestamp, text, hex_data, str(sender)))

                # 只保留最近的10条数据
                if len(self.uart_data) > 10:
                    self.uart_data = self.uart_data[:10]

                # 设置数据更新标志
                self.data_updated.set()

        except:
            timestamp = time.strftime("%H:%M:%S")
            hex_data = data.hex()
            print(f"[{timestamp}] 📥 UART原始数据来自 {sender}: {hex_data}")

            # 使用锁保护共享数据
            with self.uart_lock:
                # 添加新数据到列表开头（最新的在前面）
                self.uart_data.insert(0, (timestamp, None, hex_data, str(sender)))

                # 只保留最近的10条数据
                if len(self.uart_data) > 10:
                    self.uart_data = self.uart_data[:10]

                # 设置数据更新标志
                self.data_updated.set()

        # 添加新的菜单选项来显示解析后的数据
        async def display_parsed_data(self):
            """显示解析后的数据"""
            rocker_data = self.uart_parser.get_rocker_data()
            key_data = self.uart_parser.get_key_data()

            print("\n" + "=" * 40)
            print("解析后的数据状态")
            print("=" * 40)

            print(f"🎮 摇杆数据:")
            print(f"  当前帧号: {rocker_data['frame_num']}")
            print(f"  X轴: {rocker_data['rocker1']}")
            print(f"  Y轴: {rocker_data['rocker2']}")
            print(f"  帧错误: {rocker_data['rocker_err']} 次")

            print(f"\n🔘 按键数据:")
            print(f"  当前帧号: {key_data['frame_num']}")
            print(f"  按键状态: {key_data['key_status']} (0b{bin(key_data['key_status'])[2:].zfill(8)})")
            print(f"  帧错误: {key_data['aj_err']} 次")

            # 显示最近原始数据
            raw_log = self.uart_parser.get_raw_data_log(5)
            if raw_log:
                print(f"\n📋 最近原始数据:")
                for timestamp, hex_data, length in raw_log:
                    print(f"  [{timestamp}] 长度={length}: {hex_data}")

    def get_uart_data(self):
        """获取UART数据的线程安全方法"""
        with self.uart_lock:
            # 返回数据的副本，避免在显示时数据被修改
            return self.uart_data.copy()

    def clear_uart_data(self):
        """清空UART数据的线程安全方法"""
        with self.uart_lock:
            self.uart_data.clear()

    def get_uart_data_count(self):
        """获取UART数据数量的线程安全方法"""
        with self.uart_lock:
            return len(self.uart_data)

    async def display_uart_data(self):
        """显示UART数据的专用方法"""
        uart_data = self.get_uart_data()
        count = self.get_uart_data_count()

        print(f"\nUART数据记录 (共{count}条，显示最近10条):")
        if uart_data:
            for i, (timestamp, text, hex_data, sender) in enumerate(uart_data, 1):
                if text and text.strip():
                    print(f"  {i}. [{timestamp}] {text} (来自: {sender})")
                else:
                    print(f"  {i}. [{timestamp}] 十六进制: {hex_data} (来自: {sender})")
        else:
            print("  暂无UART数据")

    async def connect_to_device(self, device_address, timeout=15.0):
        """连接到指定设备"""
        print(f"\n正在连接到设备: {device_address}")

        # Windows特殊处理
        if self.is_windows:
            formatted_address = self._format_mac_address(device_address)
            print(f"Windows格式MAC地址: {formatted_address}")
        else:
            formatted_address = device_address

        # 清理旧的连接
        if self.connected_client:
            try:
                await self.disconnect(quiet=True)
            except:
                pass

        try:
            # Windows特殊配置
            if self.is_windows:
                client = BleakClient(
                    formatted_address,
                    disconnected_callback=self._disconnected_callback,
                    timeout=timeout,
                    winrt=dict(
                        use_cached_services=False,
                        attempt_pairing=False,
                    )
                )
            else:
                client = BleakClient(
                    formatted_address,
                    disconnected_callback=self._disconnected_callback,
                    timeout=timeout
                )

            print(f"步骤1: 尝试连接 (超时: {timeout}秒)...")

            connected = await client.connect()

            if connected:
                print(f"✅ 成功连接到设备: {device_address}")
                self.connected_client = client
                self.connection_status = True
                self.current_device_address = device_address
                self.reconnect_attempts = 0

                # 保存设备信息到JSON
                if device_address in self.devices:
                    device_info = self.devices[device_address]
                    self.save_connected_device_info(device_info)

                    # 显示连接统计
                    stats = self.get_device_connection_stats(device_address)
                    if stats:
                        print(f"📊 连接统计: 第{stats['connection_count']}次连接")

                # 设置电池服务
                await self.setup_battery_service()

                await asyncio.sleep(0.5)

                if self.connection_callbacks['on_connected']:
                    self.connection_callbacks['on_connected'](device_address)

                return client
            else:
                print("❌ 连接失败：无法建立连接")
                return None

        except asyncio.TimeoutError:
            print(f"❌ 连接超时（{timeout}秒）")
            if self.connection_callbacks['on_connection_failed']:
                self.connection_callbacks['on_connection_failed'](device_address, "timeout")
            return None
        except Exception as e:
            print(f"❌ 连接错误: {e}")
            if self.connection_callbacks['on_connection_failed']:
                self.connection_callbacks['on_connection_failed'](device_address, str(e))
            return None

    async def connect_with_windows_strategy(self, device_address, timeout=15.0):
        """Windows专用连接策略"""
        if not self.is_windows:
            return await self.connect_to_device(device_address, timeout)

        print("🔄 使用Windows专用连接策略...")

        # 策略1: 直接使用扫描到的地址
        print("🔧 策略1: 使用原始MAC地址...")
        client = await self.connect_to_device(device_address, timeout)
        if client and client.is_connected:
            return client

        # 策略2: 移除冒号
        print("🔧 策略2: 使用无冒号MAC地址...")
        address_no_colon = device_address.replace(':', '')
        client = await self.connect_to_device(address_no_colon, timeout)
        if client and client.is_connected:
            return client

        # 策略3: 大写字母
        print("🔧 策略3: 使用大写MAC地址...")
        address_upper = device_address.upper()
        client = await self.connect_to_device(address_upper, timeout)
        if client and client.is_connected:
            return client

        # 策略4: 大写无冒号
        print("🔧 策略4: 使用大写无冒号MAC地址...")
        address_upper_no_colon = device_address.replace(':', '').upper()
        client = await self.connect_to_device(address_upper_no_colon, timeout)
        if client and client.is_connected:
            return client

        print("❌ 所有Windows连接策略都失败")
        return None

    async def debug_windows_bluetooth(self):
        """Windows蓝牙调试信息"""
        if not self.is_windows:
            return

        print("\n🔧 Windows蓝牙调试信息:")

        try:
            # 检查蓝牙适配器状态
            import subprocess
            result = subprocess.run(['powershell', 'Get-PnpDevice -Class Bluetooth'],
                                    capture_output=True, text=True)
            if 'OK' in result.stdout:
                print("✅ 蓝牙适配器状态: 正常")
            else:
                print("❌ 蓝牙适配器状态: 异常")
        except:
            print("⚠️ 无法获取蓝牙适配器状态")

        # 显示扫描到的设备
        print(f"📱 扫描到的设备: {len(self.devices)} 个")
        for addr, info in self.devices.items():
            print(f"   - {info['name']}: {addr} (RSSI: {info['rssi']})")

    async def connect_with_retry(self, device_address, max_retries=3, timeout=15.0):
        """带重试的连接方法"""
        for attempt in range(1, max_retries + 1):
            print(f"\n尝试连接 ({attempt}/{max_retries})...")

            if self.is_windows and attempt > 1:
                # 在Windows上，重试时使用不同的策略
                client = await self.connect_with_windows_strategy(device_address, timeout)
            else:
                client = await self.connect_to_device(device_address, timeout)

            if client and client.is_connected:
                return client
            else:
                if attempt < max_retries:
                    wait_time = attempt * 2
                    print(f"等待 {wait_time} 秒后重试...")
                    await asyncio.sleep(wait_time)

        print("❌ 所有重试都失败")
        return None

    async def start_notifications(self, characteristic_uuid, callback: Callable):
        """启用特征通知"""
        if not self.connected_client or not self.connected_client.is_connected:
            print("设备未连接，无法启用通知")
            return False

        try:
            await self.connected_client.start_notify(characteristic_uuid, callback)
            self.notification_handlers[characteristic_uuid] = callback
            print(f"✅ 已启用通知: {characteristic_uuid}")
            return True
        except Exception as e:
            print(f"❌ 启用通知失败: {e}")
            return False

    async def stop_notifications(self, characteristic_uuid):
        """停止特征通知"""
        if not self.connected_client or not self.connected_client.is_connected:
            print("设备未连接")
            return False

        try:
            await self.connected_client.stop_notify(characteristic_uuid)
            if characteristic_uuid in self.notification_handlers:
                del self.notification_handlers[characteristic_uuid]
            print(f"✅ 已停止通知: {characteristic_uuid}")
            return True
        except Exception as e:
            print(f"❌ 停止通知失败: {e}")
            return False

    async def check_connection_status(self):
        """检查连接状态"""
        if self.connected_client:
            try:
                # 尝试一个简单的操作来验证连接是否真的有效
                status = self.connected_client.is_connected
                self.connection_status = status
                return status
            except Exception as e:
                print(f"连接状态检查错误: {e}")
                self.connection_status = False
                return False
        else:
            self.connection_status = False
            return False

    # async def read_battery_level(self):
    #     """读取电池电量 - 增强版本"""
    #     if not self.connected_client:
    #         self.battery_level = None
    #         self.battery_voltage = None
    #         return None, None
    #
    #     # 检查连接状态
    #     if not await self.check_connection_status():
    #         print("设备未连接，无法读取电池电量")
    #         self.battery_level = None
    #         self.battery_voltage = None
    #         return None, None
    #     try:
    #         value = await self.connected_client.read_gatt_char(self.UUID_BATTERY_CHAR_READ)
    #
    #         if value:
    #             # 使用电池数据解析器
    #             battery_percentage, battery_voltage = self.battery_parser.parse_battery_data(value)
    #
    #             self.battery_level = battery_percentage
    #             self.battery_voltage = battery_voltage
    #
    #             return battery_percentage, battery_voltage
    #         else:
    #             print("❌ 读取的电池数据为空")
    #             self.battery_level = None
    #             self.battery_voltage = None
    #             return None, None
    #     except Exception as e:
    #         # 如果是连接相关的错误，更新连接状态
    #         if "已中止" in str(e) or "已关闭" in str(e):
    #             print("连接已断开，停止电池监控")
    #             self.connection_status = False
    #             self.battery_level = None
    #             self.battery_voltage = None
    #         else:
    #             print(f"❌ 读取电池电量失败: {e}")
    #             self.battery_level = None
    #             self.battery_voltage = None
    #         return None, None

    # async def read_battery_with_delay(self, delay_seconds=1):
    #     """带延迟的电池读取（模拟Android版本）"""
    #     print(f"⏳ 等待 {delay_seconds} 秒后读取电池数据...")
    #     await asyncio.sleep(delay_seconds)
    #
    #     return await self.read_battery_level()

    def enable_battery_data_saving(self, enable=True):
        """启用/禁用电池数据保存"""
        self.battery_parser.set_save_battery_flag(enable)

    def start_monitoring_threads(self):
        """启动所有监控线程"""
        self.running = True

        # 移除电池监控线程，因为现在使用通知方式
        # 只保留连接状态监控和按键监听

        # 连接状态监控线程
        connection_thread = threading.Thread(target=self._connection_monitor_worker, daemon=True)
        connection_thread.start()
        self.threads.append(connection_thread)

        # 按键监听线程
        keyboard_thread = threading.Thread(target=self._keyboard_listener_worker, daemon=True)
        keyboard_thread.start()
        self.threads.append(keyboard_thread)

        print("✅ 监控线程已启动")
        print("   - 连接监控: 每5秒检查一次")
        print("   - 自动重连: 连接断开时自动重连")
        print("   - 电池监控: 使用通知方式，无需主动读取")
        print("   - 按键监听: ESC键退出程序")

    def stop_monitoring_threads(self):
        """停止所有监控线程"""
        self.running = False
        print("🛑 停止监控线程...")

    # def _battery_monitor_worker(self):
    #     """电池监控工作线程"""
    #     asyncio.run(self._battery_monitor_async())

    # async def _battery_monitor_async(self):
    #     """电池监控异步任务"""
    #     last_print_time = 0
    #     consecutive_failures = 0
    #
    #     while self.running:
    #         try:
    #             # 只有在连接状态下才读取电池
    #             if self.connection_status:
    #                 percentage, voltage = await self.read_battery_level()
    #
    #                 if percentage is not None:
    #                     print(f"🔋 电池电量(百分比%): {percentage}%")
    #                     if voltage is not None:
    #                         print(f"🔋 电池电量(电压mv): {voltage}")
    #                     consecutive_failures = 0
    #                 else:
    #                     consecutive_failures += 1
    #                     if consecutive_failures <= 3:  # 只显示前3次失败
    #                         print("🔋 电池电量: 读取失败")
    #             else:
    #                 # 未连接时重置失败计数
    #                 consecutive_failures = 0
    #
    #             await asyncio.sleep(5)  # 每5秒检查一次
    #         except Exception as e:
    #             print(f"电池监控错误: {e}")
    #             await asyncio.sleep(5)

    def _connection_monitor_worker(self):
        """连接状态监控工作线程"""
        asyncio.run(self._connection_monitor_async())

    async def _connection_monitor_async(self):
        """连接状态监控异步任务"""
        last_status = None
        last_print_time = 0

        while self.running:
            try:
                current_status = await self.check_connection_status()
                current_time = time.time()

                # 状态变化时立即打印
                if current_status != last_status:
                    status_text = "✅ 已连接" if current_status else "❌ 已断开"
                    print(f"📡 连接状态: {status_text}")
                    last_status = current_status

                # 每5秒打印一次状态（即使状态未变化）
                if current_time - last_print_time >= 5:
                    status_text = "✅ 已连接" if current_status else "❌ 已断开"
                    print(f"📡 连接状态: {status_text}")
                    last_print_time = current_time

                await asyncio.sleep(1)  # 每秒检查一次
            except Exception as e:
                print(f"连接监控错误: {e}")
                await asyncio.sleep(5)

    def _keyboard_listener_worker(self):
        """键盘监听工作线程"""
        print("⌨️  按键监听已启动 - 按ESC键退出程序")

        while self.running:
            try:
                if keyboard.is_pressed('esc'):
                    print("\n🛑 检测到ESC键，正在退出程序...")
                    self.stop_monitoring_threads()
                    asyncio.run(self._async_shutdown())
                    break
                time.sleep(0.1)
            except Exception as e:
                print(f"按键监听错误: {e}")
                break

    async def _async_shutdown(self):
        """异步关闭程序"""
        await self.disconnect()
        print("👋 程序退出")
        sys.exit(0)

    async def display_services(self, client=None):
        """显示设备的服务和特征"""
        if client is None:
            client = self.connected_client

        if not client or not client.is_connected:
            print("设备未连接，无法获取服务")
            return

        print("\n" + "=" * 50)
        print("设备服务列表:")
        print("=" * 50)

        try:
            services = client.services
            service_count = 0
            characteristic_count = 0

            for service in services:
                service_count += 1
                print(f"\n🔧 服务 [{service_count}]: {service.uuid}")
                print(f"   描述: {service.description}")

                for characteristic in service.characteristics:
                    characteristic_count += 1
                    print(f"   📍 特征 [{characteristic_count}]: {characteristic.uuid}")
                    print(f"      描述: {characteristic.description}")
                    print(f"      属性: {', '.join(characteristic.properties)}")

                    if 'read' in characteristic.properties:
                        try:
                            value = await client.read_gatt_char(characteristic.uuid)
                            if value:
                                hex_value = value.hex()
                                ascii_value = ''.join(chr(b) if 32 <= b <= 126 else '.' for b in value)
                                print(f"      值: {hex_value} (ASCII: {ascii_value})")
                        except Exception as e:
                            print(f"      值: 读取失败 - {e}")
                    else:
                        print(f"      值: [不可读]")

            print(f"\n总计: {service_count} 个服务, {characteristic_count} 个特征")

        except Exception as e:
            print(f"❌ 获取服务列表错误: {e}")

    async def read_characteristic(self, characteristic_uuid, client=None):
        """读取特征值"""
        if client is None:
            client = self.connected_client

        if not client or not client.is_connected:
            print("设备未连接")
            return None

        try:
            if not self._is_valid_uuid(characteristic_uuid):
                print("❌ UUID格式错误")
                return None

            characteristic = self._find_characteristic(characteristic_uuid)
            if not characteristic:
                print("❌ 未找到该特征")
                return None

            if 'read' not in characteristic.properties:
                print(f"❌ 该特征不支持读取操作")
                print(f"   支持的属性: {', '.join(characteristic.properties)}")
                return None

            value = await client.read_gatt_char(characteristic_uuid)
            hex_value = value.hex()
            ascii_value = ''.join(chr(b) if 32 <= b <= 126 else '.' for b in value)

            print(f"📖 读取特征 {characteristic_uuid}:")
            print(f"   十六进制: {hex_value}")
            print(f"   ASCII: {ascii_value}")
            print(f"   原始数据: {value}")
            print(f"   十进制: {list(value)}")

            return value
        except Exception as e:
            print(f"❌ 读取特征错误: {e}")
            return None

    async def write_characteristic(self, characteristic_uuid, data, client=None):
        """写入特征值"""
        if client is None:
            client = self.connected_client

        if not client or not client.is_connected:
            print("设备未连接")
            return False

        try:
            if not self._is_valid_uuid(characteristic_uuid):
                print("❌ UUID格式错误")
                return False

            characteristic = self._find_characteristic(characteristic_uuid)
            if not characteristic:
                print("❌ 未找到该特征")
                return False

            if not any(prop in characteristic.properties for prop in ['write', 'write-without-response']):
                print(f"❌ 该特征不支持写入操作")
                print(f"   支持的属性: {', '.join(characteristic.properties)}")
                return False

            if isinstance(data, str):
                if data.startswith('0x'):
                    data_bytes = bytes.fromhex(data[2:])
                elif all(c in '0123456789abcdefABCDEF' for c in data.replace(' ', '')):
                    data_bytes = bytes.fromhex(data.replace(' ', ''))
                else:
                    data_bytes = data.encode('utf-8')
            elif isinstance(data, int):
                data_bytes = bytes([data])
            else:
                data_bytes = data

            await client.write_gatt_char(characteristic_uuid, data_bytes)
            print(f"📝 写入特征 {characteristic_uuid}: {data_bytes.hex()}")
            return True
        except Exception as e:
            print(f"❌ 写入特征错误: {e}")
            return False

    def _is_valid_uuid(self, uuid_str):
        """验证UUID格式"""
        import re
        uuid_pattern = re.compile(r'^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$', re.I)
        return bool(uuid_pattern.match(uuid_str))

    def _find_characteristic(self, characteristic_uuid):
        """查找特征对象"""
        if not self.connected_client:
            return None

        for service in self.connected_client.services:
            for char in service.characteristics:
                if char.uuid.lower() == characteristic_uuid.lower():
                    return char
        return None

    async def disconnect(self, quiet=False):
        """断开连接"""
        self.stop_monitoring_threads()

        if self.connected_client:
            try:
                # 停止所有通知
                notification_uuids = list(self.notification_handlers.keys())
                for char_uuid in notification_uuids:
                    try:
                        await self.stop_notifications(char_uuid)
                        print(f"🔌 已停止通知: {char_uuid}")
                    except Exception as e:
                        print(f"⚠️ 停止通知 {char_uuid} 时出错: {e}")

                # 断开连接
                if self.connected_client.is_connected:
                    await self.connected_client.disconnect()
                    if not quiet:
                        print("🔌 已断开设备连接")

                # 清理状态
                self.connected_client = None
                self.connection_status = False
                self.current_device_address = None

                # 重置电池数据
                self.battery_level = None
                self.battery_voltage = None

                # 清空通知处理器
                self.notification_handlers.clear()

                return True
            except Exception as e:
                if not quiet:
                    print(f"❌ 断开连接错误: {e}")
                return False
        else:
            if not quiet:
                print("⚠️ 没有连接的设备")
            return True

